home *** CD-ROM | disk | FTP | other *** search
- /* if UNIX: cc -O cpr.c
- * if MSDOS: cc -O -DMSDOS cpr.c
- * if VMS: define sys sys$library; cc cpr.c
- *
- * This program prints the files named in its argument list, preceding
- * the output with a table of contents. Each file is assumed to be C
- * source code (but doesn't have to be) in that the program searches
- * for the beginning and end of functions. Function names are added to
- * the table of contents, provided the name starts at the beginning of
- * a line. The function name in the output is bolded.
- *
- * By default blank space is inserted after every closing '}'
- * character. Thus functions and structure declarations are nicely
- * isolated in the output. The only drawback to this is that structure
- * initialization tables sometimes produce lots of white space.
- * The "-r" option removes this space, or changes it to the indicated
- * length.
- *
- * The option "-l" indicates that the following argument is to be
- * the page length used for output (changing the page length hasn't been
- * tested much).
- *
- * The option "-s" indicates that the table of contents should be sorted
- * by function name within each file.
- *
- * The option "-n" indicates that output lines should be numbered with
- * the corresponding line number from the input file.
- *
- * The option "-p" indicates what proportion of the page in steps of 16
- * should be used for deciding if a new function needs a new page.
- * That is -p12 (the default) indicates that if a function starts
- * within the top 12/16 (3/4) of the page then do it, otherwise put it
- * on a new page. Thus the higher the number (upto 16) the closer to
- * the bottom of the page will functions be started. -p0 says put each
- * func on a new page.
- *
- * Try it! You'll like it. (I call it cpr.c)
- *
- * Written by:
- * Paul Breslin
- * Human Computing Resources Corp.
- * 10 St. Mary St.
- * Toronto, Ontario
- * Canada, M4Y 1P9
- *
- * -- ...!decvax!utcsrgv!hcr!phb
- *
- * Sorting and standard input reading from:
- * Rick Wise, CALCULON Corp., Rockville, MD.
- * -- ...!decvax!harpo!seismo!rlgvax!cvl!umcp-cs!cal-unix!wise
- *
- * File modified time,
- * numbered output,
- * optional white space,
- * improved function start tests from:
- * David Wasley, U.C.Berkeley
- * -- ...!ucbvax!topaz.dlw
- * Modified the -r to leave variable amounts of space
- * Patrick Powell, U. Waterloo
- *
- * Changed handling of form feeds to start a new page AND print heading:
- * Terry Doner, U of Waterloo
- *
- * Fixed up to locate more functions, and added -p option
- * Dennis Vadura, U of Waterloo
- * dvadura@watdragon.waterloo.edu (Dennis Vadura)
- *
- * It will find things like struct foo *f()...
- * but not things like int
- * f
- * ()...
- * ie. the constraint is that the () must appear on the same line
- * as the function name.
- *
- * Clean up a bit for 80286 machines (lints a bit cleaner, too)
- * Dan Frank, Prairie Computing
- *
- * Fixed a whole bunch of stuff and added lots of new flags.
- * -S sort and be case insensitive.
- * -N start numbering pages at 1 for each new file
- * -T title cat the file title before the table of contents.
- * -C print only the table of contents
- * -c only try to look for function names in files whose suffix ends
- * in .c
- * -f file to handle file containing list of files to print. (for MSDOS)
- * Dennis Vadura
- *
- * Added VMS and Language support, -h, -o options, reorganized bolding, and
- * shortened long names (so page numbers aren't lost). Also put in getopt().
- * Oh yeah, expanded tabs (which wasn't what -t originally meant).
- * -h str String to put at the top of each page instead of file name.
- * -o off Number of spaces to put in front of each line of code.
- * -a lang Assume the following language. Default is AUTO (use file
- * name suffix to guess language). NONE is allowed to mean
- * don't look for function names at all.
- * -cC Dennis Vadura's -c option is thus generalized and removed.
- * -C becomes -c (VMS requires quotes around uppercase options,
- * so where possible use lower case...) New -C added to override
- * supression of table of contents for small output jobs. (NONE
- * means no table of content entries, hence none printed.)
- *
- * Adding a language involves (at least):
- * 1) Add to enum langs.
- * 2) Add recognition of language keyword (FORTRAN) to getopt().
- * 3) Add reference in man page and in Usage() function.
- * 4) Add recognition to Scan() for end of functions.
- * 5) Build a LooksLikeXXXX() to call inside LooksLikeFunction().
- * 6) Add suffix recognition to WhichLanguage().
- * Then search everywhere for Language and see if you've missed
- * anything; if so edit this comment (smile).
- *
- * John Campbell (...!arizona!naucse!jdc or CAMPBELL@NAUVAX)
- *
- * Dennis Vadura:
- * Added a few options, -i, to ignore form-feed chars in original
- * source, -O to force output for two-up printing (this option
- * affects both table of contents and the file listing output and
- * handles the -T option correctly), added -F to print only file
- * listings.
- *
- * renamed John Campbell's -h str to -H str so that -h can be used as
- * help (ie. the -? gets you in trouble in most shells and you have to
- * escape it etc.)
- *
- * Cleaned up printing of help message.
- *
- * Oh, what the hell, took the a2ps.c postscript converter and added the
- * capability to produce a postscript output file. Seems Really nice,
- * might need a bit of tweeking but hey, I don't have hours to spend.
- * It's good enough for me :-)
- *
- * To do this I hacked the code quite a bit, re-organized some functions
- * put in new ones, and made all output go through a common set of
- * routines. I also changed cpr's output format to match that of the
- * postscript code.
- *
- * I took the a2ps postscript code and embeded it into cpr, I prefered
- * this over keeping it as an included separate file, in an effort to
- * keep cpr self contained.
- *
- * Bumped the version # to 2.5.
- */
- char *version = "2.5"; /* Just a guess--never had one before. */
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <signal.h>
- #include <string.h>
- #ifdef __TURBOC__
- #define MSDOS 1
- #endif
- #ifndef VMS
- extern int errno; /* system error number */
- extern char *sys_errlist[]; /* error message */
- #define CANT_OPEN(p1) \
- fprintf(stderr,"%s: Can't open file '%s': %s\n", \
- ProgName, p1, sys_errlist[errno] )
- #else
- #include <perror.h>
- #define CANT_OPEN(p1) \
- if (errno == EVMSERR) {\
- fprintf (stderr, "Can't open %s\n", p1);\
- LIB$STOP (vaxc$errno);\
- }\
- fprintf(stderr,"%s: Can't open file '%s': %s\n",\
- ProgName, p1, sys_errlist[errno] )
- #endif
- #if MSDOS || VMS
- #include "getopt.c"
- #endif
-
- extern char *malloc() ; /* important for 8086-like systems */
-
- #define FALSE 0
- #define TRUE 1
-
- #define TOC_SIZE 4096
- #define MAXLINE 256
-
- #define NEWFILE 1
- #define NEWFUNCTION 2
-
- #define SMALLC 8 /* Too few contents for a table of contents. */
- #define SMALLP 10 /* Too few pages for a table of contents. */
-
- FILE *File, *FList = NULL;
-
- int Braces; /* Keeps track of brace depth */
- int LineNumber; /* Count output lines */
- int PageNumber = 1; /* You figure this one out */
- int ActualPageCount = 0; /* Actual number of pages printed */
- int PageLength = 66; /* -l <len> Normal paper length */
- int PagePart = 12; /* Decision on paging for new fn*/
- int PageEnd; /* Accounts for space at bottom */
- int SawFunction;
- int InComment;
- int InString;
- int ResetPage=0;
- int ContentsOnly=0;
- int FilesOnly=0;
- int AlwaysContents=0;
- int CaseInsensitive=0;
- int StartOdd=0;
- int IgnoreFF=0;
-
- long FileLineNumber; /* Input file line number */
-
- char *TitleFile = NULL;
- char *ProgName;
- char Today[30];
- char *Name; /* Current file name */
- char *Header = NULL; /* User's header (-h "header") */
- char *Title = NULL;
-
- char *FileDate; /* Last modified time of file */
- char FunctionName[MAXLINE+1];
-
- char SortFlag; /* -s == sort table of contents */
- char NumberFlag; /* -n == output line numbers */
- int OffsetValue = 0; /* -o <number> Offset each line (of code) N spaces */
- int Space_to_leave = 5; /* -r<number> space to leave */
- int TabWidth = 8; /* -t <number> width of tabs */
-
- /* Language types */
- enum langs {NONE, AUTO, C, FORTRAN, ICON, LISP}
- Language = AUTO;
- /*
- Printer types (Would you believe I have to support a printer that can't
- backspace? Geesh!)
- */
- #define DUMB 0
- #define BACKSPACE 1 /* Probably most reasonable default. */
- #define ANSI 2 /* Just uses ansi escape sequences to bold */
- #define LN03 3 /* For now same as ANSI--later smaller print! */
- #define NECP5200 4 /* NEC 24 pin printer--in HS mode. */
- #define POSTSCRIPT 5 /* print on a postscript printer */
- int Printer = BACKSPACE; /* Choose your default. */
-
- extern char *optarg;
- extern int optind, opterr;
-
- static char *Toc[TOC_SIZE];
- static int TocPages[TOC_SIZE];
- static int TocCount;
-
-
- #ifdef VMS
- #include <errno.h> /* Watch out for EVMSERR (special 65535 errno) */
- #define unlink delete
- #define toupper _toupper /* Faster to use macro version. */
- /*
- Local (NAU) support for redirection, other VMS sites can leave this out,
- but then they can't use wild cards (*.c), or redirection (>cpr.out).
- If you are a VMS site and want this contact CAMPBELL@NAUVAX.bitnet.
- */
- #include "nau_utils:redexp.vms"
- #endif
- main(argc, argv)
- char **argv;
- {
- register int i;
- char *ctime();
- char *pname=NULL;
- char *s;
- time_t thetime, time();
- int c;
- enum langs start_lang, WhichLanguage();
-
- FileDate = (char *)malloc(100);
- ProgName = argv[0];
- thetime = time((time_t *)0);
- strcpy(Today,ctime(&thetime));
- if( (s = strchr(Today,'\n')) != NULL ) *s = '\0';
-
- /* Parse options. */
- while ((c = getopt (argc, argv, "cCFhisSnNOa:f:H:t:T:l:o:r:p:P:")) != EOF) {
- switch (c) {
- case 'a': /* Assume a language ('C', FORTRAN,...) */
- c = *optarg;
- switch (c) {
- case 'C':
- case 'c':
- Language = C;
- break;
- case 'F':
- case 'f':
- Language = FORTRAN;
- break;
- case 'I':
- case 'i':
- Language = ICON;
- break;
- case 'L':
- case 'l':
- Language = LISP;
- break;
- case 'N':
- case 'n':
- Language = NONE;
- break;
- case 'A':
- case 'a':
- Language = AUTO;
- break;
- default:
- fprintf (stderr, "Unknown or unsupported language\n");
- exit(1);
- }
- break;
-
- case 'F':
- ++FilesOnly;
- break;
-
- case 'O':
- ++StartOdd;
- break;
-
- case 'i':
- ++IgnoreFF;
- break;
-
- case 'f':
- if (*optarg == '-') {
- FList = stdin;
- }
- else if ((FList = fopen (optarg, "r")) == NULL) {
- fprintf (stderr, "Can't open file names list %s\n", optarg);
- exit(1);
- }
- break;
- case 'H': /* User's header */
- Header = optarg;
- break;
-
- case 't':
- TabWidth = atoi(optarg);
- if( TabWidth < 0 )
- TabWidth = 0;
- break;
-
- case 'T':
- TitleFile = optarg;
- break;
-
- case 'l':
- PageLength = atoi(optarg);
- if( PageLength < 10) PageLength = 10;
- break;
-
- case 'S':
- ++CaseInsensitive;
- case 's':
- ++SortFlag;
- break;
-
- case 'C':
- ++AlwaysContents;
- break;
-
- case 'c':
- ++ContentsOnly;
- break;
-
- case 'n':
- ++NumberFlag;
- break;
-
- case 'N':
- ++ResetPage;
- break;
-
- case 'o': /* Offset code by <number> */
- OffsetValue = atoi(optarg);
- if (OffsetValue <= 0) {
- fprintf (stderr, "Offset must be a positive integer only\n");
- exit(1);
- }
- if (OffsetValue > 32) {
- fprintf (stderr, "Offset must be less than 32\n");
- exit(1);
- }
- break;
-
- case 'r':
- /* It's ok to have a '0' from the "?" here... */
- Space_to_leave = atoi(optarg);
- break;
-
- case 'P':
- pname = optarg; /* Override printer default or CPRINTER environ */
- break;
-
- case 'p':
- PagePart = atoi(optarg);
- PagePart = PagePart <= 16 ? PagePart : 16;
- break;
-
- case 'h':
- default:
- Usage();
- break;
- }
- }
-
- start_lang = Language;
-
- Init (pname);
- StartTempFile();
-
- i = optind;
-
- if( FList == NULL && i == argc )
- { /* no file names */
- File = stdin;
- Name = "Standard Input";
- if (start_lang == AUTO) Language = C;
- List();
- }
-
- if( FList != NULL)
- {
- char b[1024];
-
- while( fgets(b, 1024, FList) != NULL )
- {
- if( strlen(b) ) b[strlen(b)-1]=0;
-
- if( strcmp(b, "-") != 0 )
- {
- if( (File = fopen( Name = b, "r" )) == NULL )
- {
- CANT_OPEN (Name);
- continue;
- }
- if (start_lang == AUTO) {
- Language = WhichLanguage (Name);
- }
- }
- else {
- Name = "Standard Input";
- if (start_lang == AUTO) Language = C;
- File = stdin;
- }
-
- List();
- if( File != stdin ) fclose(File);
- }
- }
- for(; i < argc; ++i )
- {
- if( strcmp(argv[i], "-") == 0 )
- {
- File = stdin;
- Name = "Standard Input";
- if (start_lang == AUTO) Language = C;
- List();
- }
- else {
- if( (File = fopen( Name = argv[i], "r" )) == NULL )
- {
- CANT_OPEN (Name);
- continue;
- }
- if (start_lang == AUTO) {
- Language = WhichLanguage (Name);
- }
- List();
- if( File != stdin ) fclose(File);
- }
- }
-
- if( PageNumber > 1 || LineNumber > 0 ) BlankPage();
- if( StartOdd && ((ActualPageCount % 2) != 0) ) BlankPage();
-
- Fini();
- EndTempFile();
-
- if( Printer == POSTSCRIPT ) DumpPostscriptHeader();
- DumpTableOfContents();
- DumpTempFiles();
- Done();
- }
-
- Usage()
- {
- char buf[132];
- char *p;
- sprintf( buf, "Usage: %s ", ProgName );
-
- printf("%s[-CcFhiNnOsS] [-a language] [-H header] [-l pagelen]\n", buf);
- for(p=buf; *p; *p++ = ' ' );
- printf("%s[-o offset] [-P printer] [-p[num]] [-r[num]] [-T title]\n", buf);
- printf("%s[-t tabwidth] [[-f flist] | file...]\n\n", buf );
-
- puts("OPTIONS: (first group can be combined)");
- puts(" -C - Force output of table of contents" );
- puts(" -c - Print only table of contents (implies -C, overrides -F)" );
- puts(" -F - Print only file contents" );
- puts(" -h - Provide help message (you're reading it)" );
- puts(" -i - Ignore form-feeds in original source");
- puts(" -N - Number pages of each file starting at page #1" );
- puts(" -n - Number output lines of each file" );
- puts(" -O - Force new files to start at an odd numbered actual page" );
- puts(" -s - Sort TOC by function name within each file" );
- puts(" -S - Same sort as -s, but ignore case\n" );
-
- puts(" -a language - select language class" );
- puts(" -H header - specify personal heading" );
- puts(" -l pagelen - define new pagelength" );
- puts(" -o offset - set offset from left of page" );
- puts(" -P print - select printer class" );
- puts(" -p[num] - control function placement on page" );
- puts(" -r[num] - control function spacing on page" );
- puts(" -T title - print a title from file 'title'" );
- puts(" -t tabwidth - set tabwidth" );
- puts(" -f flist - read 'flist' for list of files to print\n" );
-
- puts("Language choices are: C, FORTRAN, ICON, and LISP" );
- puts("Supported printers: DUMB, BACKSPACE, ANSI, LN03, NECP5200, and POSTSCRIPT");
- exit(1);
- }
-
- int SaveOut;
- char *TempName;
- char *Temp2Name;
-
- StartTempFile()
- {
- int Done();
- extern char *mktemp();
-
- CatchSignalsPlease(Done);
-
- SaveOut = dup(1);
- #if MSDOS | VMS
- TempName = "cpr0001.tmp";
- #else
- TempName = mktemp("/tmp/cprXXXXXX");
- #endif
- if( freopen(TempName, "w", stdout) == NULL )
- {
- CANT_OPEN (TempName);
- exit(1);
- }
- }
-
- EndTempFile()
- {
- #if MSDOS | VMS
- Temp2Name = "cpr0002.tmp";
- #else
- Temp2Name = mktemp("/tmp/cprXXXXXX");
- #endif
- if( freopen(Temp2Name, "w", stdout) == NULL )
- {
- CANT_OPEN (Temp2Name);
- exit(1);
- }
- }
-
- DumpTempFiles()
- {
- #if (MSDOS | VMS)
- FILE *f;
- char b[256];
- #endif
- register int pid, w;
-
- fclose(stdout);
-
- #if !(MSDOS || VMS)
- dup(SaveOut);
- while( (pid = fork()) < 0 ) sleep(1);
- if( pid )
- while ((w = wait((int *)0)) != pid && w != -1);
- else
- {
- CatchSignalsPlease(SIG_DFL);
-
- if( ContentsOnly )
- execl( "/bin/cat", "cat", Temp2Name, (char *)0 );
- else {
- /*
- Ok, use a heuristic to see if it is worth putting out the
- table of contents. They seem useless and annoying when cpr
- is just printing a small job. Heuristic: more than 10 entries
- in the table of contents AND more than 8 pages of output.
- */
- if( !FilesOnly && (AlwaysContents ||
- (TocCount > SMALLC && TocPages[TocCount-1] > SMALLP)))
- execl( "/bin/cat", "cat", Temp2Name, TempName, (char *)0 );
- else
- execl( "/bin/cat", "cat", TempName, (char *)0 );
- }
- fprintf(stderr, "%s: exec of /bin/cat failed: %s\n", ProgName,
- sys_errlist[errno]);
- exit(1);
- }
- #else
- CatchSignalsPlease(SIG_DFL);
- /*
- Use a heuristic to see if it is worth putting out the table of contents.
- They seem useless and annoying when cpr is printing a small job.
- Heuristic: > 10 entries in the table of contents or > 8 pages of output.
- */
- if( !FilesOnly && (AlwaysContents || (TocCount > SMALLC &&
- TocPages[TocCount-1] > SMALLP))) {
- if( (f=fopen(Temp2Name,"r")) == NULL ) {
- CANT_OPEN (Temp2Name);
- }
- else
- {
- while( fgets(b, MAXLINE, f) != NULL )
- write(SaveOut,b,strlen(b));
-
- fclose(f);
- }
- }
- if( !ContentsOnly )
- if( (f=fopen(TempName,"r")) == NULL ) {
- CANT_OPEN (TempName);
- }
- else
- {
- while( fgets(b, MAXLINE, f) != NULL )
- write(SaveOut,b,strlen(b));
-
- fclose(f);
- }
- #endif
- }
-
- Done()
- {
- CatchSignalsPlease(SIG_DFL);
-
- fclose( stdout );
- if( TempName ) unlink( TempName );
- if( Temp2Name ) unlink( Temp2Name );
-
- exit(0);
- }
-
- CatchSignalsPlease(action)
- #ifdef __TURBOC__
- void (*action)();
- #else
- int (*action)();
- #endif
- {
- if( signal(SIGINT, SIG_IGN) != SIG_IGN ) signal(SIGINT, action);
- #ifndef MSDOS
- if( signal(SIGQUIT, SIG_IGN) != SIG_IGN ) signal(SIGQUIT, action);
- if( signal(SIGHUP, SIG_IGN) != SIG_IGN ) signal(SIGHUP, action);
- #endif
- }
-
- List()
- {
- register int bp;
- register char *bufp;
- char buffer[MAXLINE];
-
- NewFile(0);
- bp = Braces = 0;
- InString = InComment = 0; /* reset for new file -DV */
-
- if (Language == C)
- SawFunction = 0;
- else if (Language == FORTRAN)
- SawFunction = 1; /* Put space after main program END card */
- else if (Language == NONE)
- Braces = 1; /* Don't even call LooksLikeFunction */
-
- bufp = buffer;
- while( fgets(bufp, MAXLINE, File) != NULL )
- {
- ++FileLineNumber;
- if( bp ) NewFunction();
-
- if( ++LineNumber >= PageEnd ) NewPage();
-
- if( bufp[0] == '\f'
- && bufp[1] == '\n'
- && bufp[2] == '\0' )
- {
- if( !IgnoreFF )
- NewPage(); /* was strcpy(bufp, "^L\n");*/
- continue;
- }
-
- if( (Braces == 0) && LooksLikeFunction(bufp) )
- AddToTableOfContents(NEWFUNCTION);
- else
- PutString(buffer, -1, NumberFlag, 1);
-
- if (Language != NONE)
- bp = Scan(buffer);
- }
- }
-
- Scan(l)
- register char *l;
- {
- extern char *EndComment();
- extern char *EndString();
- register char c;
- int bp, offset;
- char *save;
-
- bp = 0;
- switch (Language) {
- case C:
- for( save = l; c = *l; ++l )
- if( InComment )
- l = EndComment(l);
- else if( InString )
- l = EndString(l);
- else
- switch(c)
- {
- case '{':
- ++Braces;
- break;
-
- case '}':
- if( --Braces == 0 )
- bp = 1;
- break;
-
- case '\'':
- for( ++l; *l && *l != '\''; ++l )
- if( *l == '\\' && *(l+1) ) ++l;
- break;
-
- case '"':
- InString = 1;
- break;
-
- case '/':
- if( *(l+1) == '*' )
- {
- InComment = 1;
- ++l;
- }
- break;
- }
- break;
- case FORTRAN:
- /* Just check for an END card to indicate the routine is over... */
- save = l;
- while (isdigit(*l)) ++l; /* Skip over any line statements. */
- while (*l && (*l == ' ' || *l == '\t')) ++l; /* Get to non-blank */
- /* Icon really should only compare against lower case here. */
- if (save != l && (offset = Compare (l, "END"))) {
- /*
- Check to make sure it isn't an ENDIF or some other variable name
- (Unfortunately, build in a VMS ! comment checker here...)
- */
- l += offset;
- if (*l == '\n' || *l == '!') {
- Braces = 0;
- bp = 1;
- }
- }
- break;
- case ICON:
- /* Just check for an end keyword to indicate the routine is over... */
- save = l;
- while (*l && (*l == ' ' || *l == '\t')) ++l; /* Get to non-blank */
- if (l[0] == 'e' && l[1] == 'n' && l[2] == 'd') {
- /*
- Check to make sure it isn't an ENDIF or some other variable name
- */
- l += 3;
- if (*l == '\n' || *l == '#') {
- Braces = 0;
- bp = 1;
- }
- }
- break;
- case LISP:
- /*
- Lisp requires the context to be preserved, hence Braces stays 0 (a
- lie) and LooksLikeLisp() handles everything.
- */
- break;
- }
- return(bp);
- }
-
- PutString (str, len, line, newline)
- char *str;
- int len;
- int line;
- int newline;
- {
- /*
- All lines of program text that are written through here are checked for
- tabs. This should include all parts of each line of code (to keep the
- internal column counter straight).
- */
- static char *lbuf = (char *)0;
- static int lbuflen = 0;
- static char spaces[] = {" "};
- static int col = 0;
- static int front=1;
- int i, need;
- register char *d, *s, c;
-
- if (len == -1) len = strlen (str);
-
- need =(len+OffsetValue+20)<<1; /* mult by 2, so that \ work for postcript
- */
- if( need > lbuflen ) {
- if( lbuf ) free(lbuf);
- lbuflen = need;
- lbuf = (char *)malloc(lbuflen);
- if( ! lbuf ) {
- fprintf( stderr, "MALLOC error, insufficient memory\n" );
- exit(1);
- }
- }
- *lbuf = '\0';
-
- if( OffsetValue && front ) sprintf (lbuf, "%.*s", OffsetValue, spaces);
- if( line && front ) {
- sprintf (lbuf, "%6d ", FileLineNumber);
- }
- front = 0;
- col = strlen(lbuf);
- d = lbuf+col;
-
- s = str;
- for (i=0; i < len; ++i, ++s) {
- c = *s;
- switch (c) {
- case '\t':
- do {
- *d++ = ' ';
- } while (col++ % TabWidth != (TabWidth - 1));
- break;
- case '\b':
- *d++ = c;
- if (col > 0) --col;
- break;
- case '\n':
- col = 0;
- if( s[1] ) *d++ = '\n';
- break;
- case '\f':
- col = 0;
- *d++ = c;
- break;
-
- case '(':
- case ')':
- if( Printer == POSTSCRIPT ) {
- *d++ = '\\';
- *d++ = c;
- break;
- }
- /*FALLTHROUGH*/
-
- default:
- *d++ = c;
- ++col;
- }
- }
- *d++ = '\0';
-
- switch(Printer) {
- case POSTSCRIPT:
- printf( "(%s) %s\n", lbuf, newline ? "s":"sn" );
- break;
-
- default:
- printf( "%s", lbuf );
- if(newline) putchar('\n');
- break;
- }
- if( newline ) front = 1;
- }
-
- PutBold (bstr, len, flag)
- char *bstr;
- int len, flag;
- /*-
- Put ``str'' bolded on stdout (possibly using ^H's). (This test a flag
- to support other types of bolding options.) Assume ``str'' is ``len''
- characters long, unless ``len'' == -1, then use strlen for the length
- of ``str''. If ``flag'' is 0 then print here without calling PutString
- (in other words, don't pass it on as part of a code line for tab
- column counting/expansion).
-
- When working with escape sequences, don't call PutString to print out the
- escape sequences themselves. Otherwise the tab expansion will be off.
- (PutString adjusts column counter for \b's, but it doesn't need to know
- about escape sequences.)
- */
- {
- int str_flag = 0;
- char *str;
-
- if( len == -1 ) {
- len = strlen(bstr);
- str = bstr;
- }
- else {
- str_flag = 1;
- str = malloc(len+2);
- strncpy(str, bstr, len);
- }
-
- switch (Printer) {
- case DUMB:
- PutString (str, len, NumberFlag, 0); /* Just give up--printer is too
- dumb */
- break;
- case ANSI:
- case LN03:
- printf ("\033[1m");
- PutString (str, len, NumberFlag, 0);
- printf ("\033[22m");
- break;
- case NECP5200:
- printf ("\033E");
- PutString (str, len, NumberFlag, 0);
- printf ("\033F");
- break;
- case POSTSCRIPT:
- printf( "(%s) sb\n", str );
- break;
-
- case BACKSPACE:
- {
- int j, k;
- char *buf, *s;
-
- s = buf = (char *)malloc(len*3+10);
- for( k=0; *str; ) {
- *s++ = *str;
- *s++ = '\b';
- *s++ = *str++;
- k += 3;
- }
- *s++ = '\0';
- /*
- strcpy( s, str );
- s += len;
- for(k=0; k<len; k++ ) *s++='\b';
- strcpy( s, str );
- */
-
- if (flag)
- PutString (buf, k, NumberFlag, 0);
- else
- printf(buf);
- free(buf);
- }
- break;
-
- default:
- fprintf (stderr, "Unknown printer type in PutBold\n");
- exit (1);
- }
- if( str_flag ) free(str);
- }
-
- char *
- EndComment(p)
- register char *p;
- {
- register char c;
-
- /*
- * Always return pointer to last non-null char looked at.
- */
- while( c = *p++ )
- if( c == '*' && *p == '/' )
- {
- InComment = 0;
- return(p);
- }
- return(p-2);
- }
- /* cpr got too big to ship as mail so I'm splitting it here... jdc */
- #include "cpr.c2"
-